home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gdb / gdb_18s.zoo / eval.c < prev    next >
C/C++ Source or Header  |  1992-03-25  |  17KB  |  604 lines

  1. /* Evaluate expressions for GDB.
  2.    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  3.  
  4. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone
  6. for the consequences of using it or for whether it serves any
  7. particular purpose or works at all, unless he says so in writing.
  8. Refer to the GDB General Public License for full details.
  9.  
  10. Everyone is granted permission to copy, modify and redistribute GDB,
  11. but only under the conditions described in the GDB General Public
  12. License.  A copy of this license is supposed to have been given to you
  13. along with GDB so you can know your rights and responsibilities.  It
  14. should be in a file named COPYING.  Among other things, the copyright
  15. notice and this notice must be preserved on all copies.
  16.  
  17. In other words, go ahead and share GDB, but don't try to stop
  18. anyone else from sharing it farther.  Help stamp out software hoarding!
  19. */
  20.  
  21. #include "defs.h"
  22. #include "symtab.h"
  23. #include "value.h"
  24. #include "expression.h"
  25.  
  26.  
  27. /* Parse the string EXP as a C expression, evaluate it,
  28.    and return the result as a number.  */
  29.  
  30. CORE_ADDR
  31. parse_and_eval_address (exp)
  32.      char *exp;
  33. {
  34.   struct expression *expr = parse_c_expression (exp);
  35.   register CORE_ADDR addr;
  36.   register struct cleanup *old_chain
  37.     = make_cleanup (free_current_contents, &expr);
  38.  
  39.   addr = value_as_long (evaluate_expression (expr));
  40.   do_cleanups (old_chain);
  41.   return addr;
  42. }
  43.  
  44. /* Like parse_and_eval_address but takes a pointer to a char * variable
  45.    and advanced that variable across the characters parsed.  */
  46.  
  47. CORE_ADDR
  48. parse_and_eval_address_1 (expptr)
  49.      char **expptr;
  50. {
  51.   struct expression *expr = parse_c_1 (expptr, 0, 0);
  52.   register CORE_ADDR addr;
  53.   register struct cleanup *old_chain
  54.     = make_cleanup (free_current_contents, &expr);
  55.  
  56.   addr = value_as_long (evaluate_expression (expr));
  57.   do_cleanups (old_chain);
  58.   return addr;
  59. }
  60.  
  61. value
  62. parse_and_eval (exp)
  63.      char *exp;
  64. {
  65.   struct expression *expr = parse_c_expression (exp);
  66.   register value val;
  67.   register struct cleanup *old_chain
  68.     = make_cleanup (free_current_contents, &expr);
  69.  
  70.   val = evaluate_expression (expr);
  71.   do_cleanups (old_chain);
  72.   return val;
  73. }
  74.  
  75. /* Parse up to a comma (or to a closeparen)
  76.    in the string EXPP as an expression, evaluate it, and return the value.
  77.    EXPP is advanced to point to the comma.  */
  78.  
  79. value
  80. parse_to_comma_and_eval (expp)
  81.      char **expp;
  82. {
  83.   struct expression *expr = parse_c_1 (expp, 0, 1);
  84.   register value val;
  85.   register struct cleanup *old_chain
  86.     = make_cleanup (free_current_contents, &expr);
  87.  
  88.   val = evaluate_expression (expr);
  89.   do_cleanups (old_chain);
  90.   return val;
  91. }
  92.  
  93. /* Evaluate an expression in internal prefix form
  94.    such as is constructed by expread.y.
  95.  
  96.    See expression.h for info on the format of an expression.  */
  97.  
  98. static value evaluate_subexp ();
  99. static value evaluate_subexp_for_address ();
  100. static value evaluate_subexp_for_sizeof ();
  101. static value evaluate_subexp_with_coercion ();
  102.  
  103. /* Values of NOSIDE argument to eval_subexp.  */
  104. enum noside
  105. { EVAL_NORMAL, 
  106.   EVAL_SKIP,
  107.   EVAL_AVOID_SIDE_EFFECTS,
  108. };
  109.  
  110. value
  111. evaluate_expression (exp)
  112.      struct expression *exp;
  113. {
  114.   int pc = 0;
  115.   return evaluate_subexp (exp, &pc, EVAL_NORMAL);
  116. }
  117.  
  118. /* Evaluate an expression, avoiding all memory references
  119.    and getting a value whose type alone is correct.  */
  120.  
  121. value
  122. evaluate_type (exp)
  123.      struct expression *exp;
  124. {
  125.   int pc = 0;
  126.   return evaluate_subexp (exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
  127. }
  128.  
  129. static value
  130. evaluate_subexp (exp, pos, noside)
  131.      register struct expression *exp;
  132.      register int *pos;
  133.      enum noside noside;
  134. {
  135.   enum exp_opcode op;
  136.   int tem;
  137.   register int pc;
  138.   register value arg1, arg2;
  139.   int nargs;
  140.   value *argvec;
  141.  
  142.   pc = (*pos)++;
  143.   op = exp->elts[pc].opcode;
  144.  
  145.   switch (op)
  146.     {
  147.     case OP_LONG:
  148.       (*pos) += 3;
  149.       return value_from_long (exp->elts[pc + 1].type,
  150.                   exp->elts[pc + 2].longconst);
  151.  
  152.     case OP_DOUBLE:
  153.       (*pos) += 3;
  154.       return value_from_double (exp->elts[pc + 1].type,
  155.                 exp->elts[pc + 2].doubleconst);
  156.  
  157.     case OP_VAR_VALUE:
  158.       (*pos) += 2;
  159.       if (noside == EVAL_SKIP)
  160.     goto nosideret;
  161.       return value_of_variable (exp->elts[pc + 1].symbol);
  162.  
  163.     case OP_LAST:
  164.       (*pos) += 2;
  165.       return access_value_history (exp->elts[pc + 1].longconst);
  166.  
  167.     case OP_REGISTER:
  168.       (*pos) += 2;
  169.       return value_of_register (exp->elts[pc + 1].longconst);
  170.  
  171.     case OP_INTERNALVAR:
  172.       (*pos) += 2;
  173.       return value_of_internalvar (exp->elts[pc + 1].internalvar);
  174.  
  175.     case OP_FUNCALL:
  176.       (*pos) += 2;
  177.       nargs = exp->elts[pc + 1].longconst;
  178.       argvec = (value *) alloca (sizeof (value) * (nargs + 2));
  179.       for (tem = 0; tem <= nargs; tem++)
  180.  
  181.     /* Ensure that array expressions are coerced into pointer objects. */
  182.     argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
  183.       /* signal end of arglist */
  184.       argvec[tem] = 0;
  185.  
  186.       if (noside == EVAL_SKIP)
  187.     goto nosideret;
  188.       if (noside == EVAL_AVOID_SIDE_EFFECTS)
  189.     return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
  190.       return call_function (argvec[0], nargs, argvec + 1);
  191.  
  192.     case OP_STRING:
  193.       tem = strlen (&exp->elts[pc + 1].string);
  194.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  195.       if (noside == EVAL_SKIP)
  196.     goto nosideret;
  197.       return value_string (&exp->elts[pc + 1].string, tem);
  198.  
  199.     case TERNOP_COND:
  200.       /* Skip third and second args to evaluate the first one.  */
  201.       arg1 = evaluate_subexp (exp, pos, noside);
  202.       if (value_zerop (arg1))
  203.     {
  204.       evaluate_subexp (exp, pos, EVAL_SKIP);
  205.       return evaluate_subexp (exp, pos, noside);
  206.     }
  207.       else
  208.     {
  209.       arg2 = evaluate_subexp (exp, pos, noside);
  210.       evaluate_subexp (exp, pos, EVAL_SKIP);
  211.       return arg2;
  212.     }
  213.  
  214.     case STRUCTOP_STRUCT:
  215.       tem = strlen (&exp->elts[pc + 1].string);
  216.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  217.       arg1 = evaluate_subexp (exp, pos, noside);
  218.       if (noside == EVAL_SKIP)
  219.     goto nosideret;
  220.       if (noside == EVAL_AVOID_SIDE_EFFECTS)
  221. #if 0
  222.     return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
  223.                            &exp->elts[pc + 1].string,
  224.                            1),
  225.                lval_memory);
  226. #else
  227.     goto nosideret;
  228. #endif
  229.       else
  230.       {
  231.       value temp = arg1;
  232.       
  233.       return value_struct_elt (temp, &exp->elts[pc + 1].string,
  234.                    "structure");
  235.       }
  236.  
  237.     case STRUCTOP_PTR:
  238.       tem = strlen (&exp->elts[pc + 1].string);
  239.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  240.       arg1 = evaluate_subexp (exp, pos, noside);
  241.       if (noside == EVAL_SKIP)
  242.     goto nosideret;
  243.       if (noside == EVAL_AVOID_SIDE_EFFECTS)
  244. #if 0
  245.     return value_zero (lookup_struct_elt_type (TYPE_TARGET_TYPE
  246.                            (VALUE_TYPE (arg1)),
  247.                            &exp->elts[pc + 1].string,
  248.                            1),
  249.                lval_memory);
  250. #else
  251.     goto nosideret;
  252. #endif
  253.       else
  254.       {
  255.           value temp = arg1;
  256.       return value_struct_elt (temp, &exp->elts[pc + 1].string,
  257.                    "structure pointer");
  258.       }
  259.       
  260.     case BINOP_ASSIGN:
  261.       arg1 = evaluate_subexp (exp, pos, noside);
  262.       arg2 = evaluate_subexp (exp, pos, noside);
  263.       if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
  264.     return arg1;
  265.       return value_assign (arg1, arg2);
  266.  
  267.     case BINOP_ASSIGN_MODIFY:
  268.       (*pos) += 2;
  269.       arg1 = evaluate_subexp (exp, pos, noside);
  270.       arg2 = evaluate_subexp (exp, pos, noside);
  271.       if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
  272.     return arg1;
  273.       op = exp->elts[pc + 1].opcode;
  274.       if (op == BINOP_ADD)
  275.     arg2 = value_add (arg1, arg2);
  276.       else if (op == BINOP_SUB)
  277.     arg2 = value_sub (arg1, arg2);
  278.       else
  279.     arg2 = value_binop (arg1, arg2, op);
  280.       return value_assign (arg1, arg2);
  281.  
  282.     case BINOP_ADD:
  283.       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
  284.       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
  285.       if (noside == EVAL_SKIP)
  286.     goto nosideret;
  287.       return value_add (arg1, arg2);
  288.  
  289.     case BINOP_SUB:
  290.       arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
  291.       arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
  292.       if